package com.yyfax.ph.base;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import cn.jpush.android.api.CustomPushNotificationBuilder;
import cn.jpush.android.api.JPushInterface;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.facebook.stetho.Stetho;
import com.tencent.bugly.crashreport.CrashReport;
import com.umeng.analytics.AnalyticsConfig;
import com.umeng.analytics.MobclickAgent;
import com.yyfax.common.CLog;
import com.yyfax.common.cache.CacheManager;
import com.yyfax.common.lockpattern.ACache;
import com.yyfax.common.lockpattern.Constant;
import com.yyfax.common.lockpattern.LockPatternUtil;
import com.yyfax.common.lockpattern.LockPatternView;
import com.yyfax.common.tools.ManifestUtil;
import com.yyfax.common.tools.SystemTool;
import com.yyfax.infrastructure.base.BaseApplication;
import com.yyfax.infrastructure.eventbus.EventAgent;
import com.yyfax.infrastructure.mvp.IEvent;
import com.yyfax.infrastructure.network.NetworkHelper;
import com.yyfax.ph.BuildConfig;
import com.yyfax.ph.Global;
import com.yyfax.ph.R;
import com.yyfax.ph.common.GlobalVariableConfig;
import com.yyfax.ph.common.utils.Constants;
import com.yyfax.ph.common.utils.crashutils.CrashHandler;
import com.yyfax.ph.common.utils.preferenceutils.PreferenceConstants;
import com.yyfax.ph.common.utils.preferenceutils.PreferenceManager;
import com.yyfax.ph.common.widgets.shortbadger.ShortcutBadger;
import com.yyfax.ph.personal.authority.gesture.GesturesPresenter;
import com.yyfax.ph.personal.authority.jpush.PushEvent;
import com.yyfax.ph.personal.authority.login.LoginModel;

import java.util.List;

/**
 * 缓存类(PreferenceManager和CacheManager初始化)
 * 奔溃操作捕获奔溃日志类AppCrashHandler初始化工作
 */
public class YJPH extends BaseApplication {
	private static final String TAG = "YJPH";

	private static volatile YJPH mInstance;
	private PreferenceManager mPreferenceManager;

	public NetworkHelper networkHelper;
	private ACache mACache;

	public static YJPH getInstance() {
		if (mInstance == null) {
			synchronized (YJPH.class) {
				if (mInstance == null) {
					CLog.i(TAG, "initialize YJPH application ...");
					new YJPH();
				}
			}
		}
		return mInstance;
	}

	public PreferenceManager getPreferenceManager() {
		return mPreferenceManager;
	}

	public static boolean isRoboUnitTest() {
		return "robolectric".equals(Build.FINGERPRINT);
	}

	@Override
	public void onCreate() {
		super.onCreate();
		mInstance = this;
		//todo 把ActivityLifecycleCallbacks、CrashHandler与B项目的合并起来，ACache具体用法
		CrashHandler crashHandler = CrashHandler.getInstance(this);
		crashHandler.setOnCrashListener(null);
		//初始化配置参数信息
		initialization();
		//集成腾讯Bugly
		initBugly();

		registerActivityLifecycleCallbacks(new com.yyfax.ph.base.ActivityLifecycleCallbacks());
		mACache = ACache.get(this);
		if (TextUtils.equals(AnalyticsConfig.getChannel(this), "develop") && BuildConfig.DEBUG && !isRoboUnitTest()) {
			Stetho.initializeWithDefaults(this);
		}

		mPreferenceManager = new PreferenceManager(this);

		ArrayMap<String, String> params = new ArrayMap<>();
		params.put("source", Global.SOURCE);
		params.put("macId", GlobalVariableConfig.getMacId(this));
		params.put("version", BuildConfig.VERSION_NAME);
		params.put("versionCode", String.valueOf(BuildConfig.VERSION_CODE)); // 2017/11/16 云测3.0添加
		params.put("channel", channel); // 2017/11/16 云测3.0添加
		params.put("sv", "v2");
		params.put("longitude", "");
		params.put("latitude", "");
		networkHelper = NetworkHelper.getInstance(this, Global.BASE_URL, params);

		CacheManager.setSysCachePath(getCacheDir().getPath());
		initJPush();
	}

	public void initialization() {
		com.yyfax.infrastructure.Constants.DEBUG_TOGGLE = BuildConfig.DEBUG;
		com.yyfax.common.CLog.TOGGLE = BuildConfig.DEBUG;

		Global.BASE_URL = ManifestUtil.readMetaDataFromApplication(this, "REMOTE_URL");
		Constants.SHARE_SDK_KEY = ManifestUtil.readMetaDataFromApplication(this, "SHARE_SDK_KEY");
		Constants.WE_CHAT_APP_ID = ManifestUtil.readMetaDataFromApplication(this, "WE_CHAT_ID");
		Constants.WE_CHAT_SECRET = ManifestUtil.readMetaDataFromApplication(this, "WE_CHAT_SECRET");
	}

	/***
	 * 为了节省流量、内存等资源，建议初始化的时候对上报进程进行控制，
	 * 只在主进程下上报数据：判断是否是主进程（通过进程名是否为包名来判断），
	 * 并在初始化Bugly时增加一个上报进程的策略配置。
	 */
	private void initBugly() {
		String packageName = getPackageName();
		String processName = SystemTool.getProcessName(android.os.Process.myPid());
		CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(this);
		strategy.setUploadProcess(processName == null || processName.equals(packageName));// 设置是否为上报进程
		CrashReport.initCrashReport(this, strategy);
	}

	private void initJPush() {
		JPushInterface.setDebugMode(Constants.IS_DEBUG);//设置开启日志,发布时请关闭日志
		JPushInterface.init(this);//初始化JPush
		String rid = JPushInterface.getRegistrationID(this);//获取注册ID
		CustomPushNotificationBuilder builder = new CustomPushNotificationBuilder(
				getApplicationContext(),
				R.layout.customer_notitfication_layout,
				R.id.icon, R.id.title, R.id.text);//指定定制的Notification Layout
		builder.statusBarDrawable = R.drawable.ic_launcher;//指定最顶层状态栏小图标
		builder.layoutIconDrawable = R.drawable.ic_launcher;//指定下拉状态栏时显示的通知图标
		builder.developerArg0 = "developerArg2";
		JPushInterface.setPushNotificationBuilder(2, builder);
	}

	/**
	 * 解绑极光账号 清除极光消息
	 */
	public void clearJPush() {
		JPushInterface.clearAllNotifications(this);
		ShortcutBadger.applyCount(this, 0);
		EventAgent.post(new PushEvent(true));
		mPreferenceManager.savePreference(PreferenceConstants.SP_KEY_UNREAD_PUSH_MESSAGE_COUNT, 0);
	}

	public static void reportError(String error) {
		try {
			Context ctx = getInstance();
			MobclickAgent.reportError(ctx, error);
		} catch (Exception ex) {
			CLog.e(TAG, "report error string to mob click failure.");
		}
	}

	public static void reportError(Throwable e) {
		try {
			Context ctx = getInstance();
			MobclickAgent.reportError(ctx, e);
		} catch (Exception ex) {
			CLog.e(TAG, "report error throwable to mob click failure.");
		}
	}

	public void onLoginSuccess(LoginModel.LoginContentBean bean) {
		mPreferenceManager.savePreference(PreferenceConstants.SP_KEY_LOGIN_SUCCESS_FLAG, true);
		//1.如果切换了账户，需要清除手势密码
		String userId = bean.id;
		if (!mPreferenceManager.getUserId("").equalsIgnoreCase(userId)) {
			JPushInterface.clearAllNotifications(this);
			mPreferenceManager.savePreference(PreferenceConstants.SP_KEY_UNREAD_PUSH_MESSAGE_COUNT, 0);
			mPreferenceManager.savePreference(PreferenceConstants.SP_KEY_FIRST_LOGIN, true);
			CacheManager.clearCache(Constants.CUSTOMER_MANAGER);//清除记住过的客户经理编号
			clearGesture(false);//清除手势密码
		}
		//2.保存账号信息
		mPreferenceManager
				.savePreference(PreferenceConstants.SP_KEY_USER_ID, userId)
				.savePreference(PreferenceConstants.SP_KEY_USER_NAME, bean.name)
				.savePreference(PreferenceConstants.SP_KEY_USER_TYPE, bean.userType)
				.savePreference(PreferenceConstants.SP_KEY_USER_PHONE, bean.phone)
				.savePreference(PreferenceConstants.SP_KEY_LOGIN_TOKEN_FLAG, bean.token)
				.savePreference(PreferenceConstants.SP_KEY_USER_RECOMMEND_FLAG, bean.rcmdFlag)
				.savePreference(PreferenceConstants.SP_KEY_RECOMMEND_CODE, bean.id)
				.savePreference(PreferenceConstants.SP_KEY_LOGIN_SUCCESS_FLAG, true)
				.savePreference(PreferenceConstants.SP_KEY_CAN_RECOMMEND_FLAG, bean.delFlag);
	}

	public void onLogoutSuccess() {
		YJPH.getInstance().getPreferenceManager()
				.savePreference(PreferenceConstants.SP_KEY_USER_NAME, "")
				.savePreference(PreferenceConstants.SP_KEY_USER_CODE, "")
				.savePreference(PreferenceConstants.SP_KEY_RECOMMEND_CODE, "")
				.savePreference(PreferenceConstants.SP_KEY_LOGIN_SUCCESS_FLAG, false)
				.savePreference(PreferenceConstants.SP_KEY_USER_TYPE, -1)
				.savePreference(PreferenceConstants.SP_KEY_LOGIN_TOKEN_FLAG, "")
				.savePreference(PreferenceConstants.SP_KEY_CAN_RECOMMEND_FLAG, 0);
		mPreferenceManager.savePreference(PreferenceConstants.SP_KEY_LOGIN_SUCCESS_FLAG, false);
	}

	/**
	 * 隐藏输入法(Activity)
	 */
	public static void hideInputWindow(Activity activity) {
		try {
			View view = activity.getCurrentFocus();
			if (view != null) {
				// 设置输入法输入完成时对话框自动隐藏
				((InputMethodManager) getInstance().getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
				view.clearFocus();//清除当前view的焦点
			}
		} catch (Exception e) {
			CLog.e(TAG, "hideInputWindow.Exception: " + e.getMessage());
		}
	}

	public int color(int resId) {
		return getResources().getColor(resId);
	}

	public Drawable drawable(int resId) {
		return getResources().getDrawable(resId);
	}

	public String[] stringArray(int resId) {
		return getResources().getStringArray(resId);
	}

	public boolean checkChosenPattern(List<LockPatternView.Cell> cells) {
		byte[] oldPattern = mACache.getAsBinary(Constant.GESTURE_PASSWORD);
		CLog.i(TAG, "checkChosenPattern oldPattern != null=" + (oldPattern != null));
		return LockPatternUtil.checkPattern(cells, oldPattern);
	}

	public void saveChosenPattern(List<LockPatternView.Cell> cells) {
		byte[] bytes = LockPatternUtil.patternToHash(cells);
		mACache.put(Constant.GESTURE_PASSWORD, bytes);
	}

	public void removeChosenPattern() {
		mACache.remove(Constant.GESTURE_PASSWORD);
	}

	public boolean hadLockPattern() {
		byte[] pattern = mACache.getAsBinary(Constant.GESTURE_PASSWORD);
		CLog.i(TAG, "hadLockPattern Constant.GESTURE_PASSWORD=" + (Constant.GESTURE_PASSWORD));
		CLog.i(TAG, "hadLockPattern oldPattern != null=" + (pattern != null));
		return pattern != null;
	}

	public void clearGesture(boolean logout) {
		YJPH.getInstance().getPreferenceManager().savePreference(PreferenceConstants.SP_KEY_VALIDATE_GESTURE, false);
		GesturesPresenter.resetGestureCount();
		GesturesPresenter.writeStatus(false);
		removeChosenPattern();
		if (logout) {
			EventAgent.postSticky(new IEvent.UnLoginEvent(IEvent.CODE_UNLOGIN));
		}
	}

	public static void load(Context ctx, String url, ImageView imageView, int placeholder, int error) {
		Glide.with(ctx).load(getHeaderGlideUrl(url)).placeholder(placeholder).fitCenter().error(error).into(imageView);
	}

	public static void load(Context ctx, String url, ImageView imageView, int placeholder) {
		Glide.with(ctx).load(getHeaderGlideUrl(url)).placeholder(placeholder).fitCenter().into(imageView);
	}

	public static void load(Context ctx, String url, ImageView imageView) {
		Glide.with(ctx).load(getHeaderGlideUrl(url)).fitCenter().into(imageView);
	}

	private static GlideUrl getHeaderGlideUrl(String url) {
		return new GlideUrl(url, new LazyHeaders.Builder().build());
	}
}
